home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / g_save.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-13  |  17.3 KB  |  745 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20.  
  21. #include "g_local.h"
  22.  
  23. field_t fields[] = {
  24.     {"classname", FOFS(classname), F_LSTRING},
  25.     {"origin", FOFS(s.origin), F_VECTOR},
  26.     {"model", FOFS(model), F_LSTRING},
  27.     {"spawnflags", FOFS(spawnflags), F_INT},
  28.     {"speed", FOFS(speed), F_FLOAT},
  29.     {"accel", FOFS(accel), F_FLOAT},
  30.     {"decel", FOFS(decel), F_FLOAT},
  31.     {"target", FOFS(target), F_LSTRING},
  32.     {"targetname", FOFS(targetname), F_LSTRING},
  33.     {"pathtarget", FOFS(pathtarget), F_LSTRING},
  34.     {"deathtarget", FOFS(deathtarget), F_LSTRING},
  35.     {"killtarget", FOFS(killtarget), F_LSTRING},
  36.     {"combattarget", FOFS(combattarget), F_LSTRING},
  37.     {"message", FOFS(message), F_LSTRING},
  38.     {"team", FOFS(team), F_LSTRING},
  39.     {"wait", FOFS(wait), F_FLOAT},
  40.     {"delay", FOFS(delay), F_FLOAT},
  41.     {"random", FOFS(random), F_FLOAT},
  42.     {"move_origin", FOFS(move_origin), F_VECTOR},
  43.     {"move_angles", FOFS(move_angles), F_VECTOR},
  44.     {"style", FOFS(style), F_INT},
  45.     {"count", FOFS(count), F_INT},
  46.     {"health", FOFS(health), F_INT},
  47.     {"sounds", FOFS(sounds), F_INT},
  48.     {"light", 0, F_IGNORE},
  49.     {"dmg", FOFS(dmg), F_INT},
  50.     {"angles", FOFS(s.angles), F_VECTOR},
  51.     {"angle", FOFS(s.angles), F_ANGLEHACK},
  52.     {"mass", FOFS(mass), F_INT},
  53.     {"volume", FOFS(volume), F_FLOAT},
  54.     {"attenuation", FOFS(attenuation), F_FLOAT},
  55.     {"map", FOFS(map), F_LSTRING},
  56.  
  57.     // temp spawn vars -- only valid when the spawn function is called
  58.     {"lip", STOFS(lip), F_INT, FFL_SPAWNTEMP},
  59.     {"distance", STOFS(distance), F_INT, FFL_SPAWNTEMP},
  60.     {"height", STOFS(height), F_INT, FFL_SPAWNTEMP},
  61.     {"noise", STOFS(noise), F_LSTRING, FFL_SPAWNTEMP},
  62.     {"pausetime", STOFS(pausetime), F_FLOAT, FFL_SPAWNTEMP},
  63.     {"item", STOFS(item), F_LSTRING, FFL_SPAWNTEMP},
  64.     {"gravity", STOFS(gravity), F_LSTRING, FFL_SPAWNTEMP},
  65.     {"sky", STOFS(sky), F_LSTRING, FFL_SPAWNTEMP},
  66.     {"skyrotate", STOFS(skyrotate), F_FLOAT, FFL_SPAWNTEMP},
  67.     {"skyaxis", STOFS(skyaxis), F_VECTOR, FFL_SPAWNTEMP},
  68.     {"minyaw", STOFS(minyaw), F_FLOAT, FFL_SPAWNTEMP},
  69.     {"maxyaw", STOFS(maxyaw), F_FLOAT, FFL_SPAWNTEMP},
  70.     {"minpitch", STOFS(minpitch), F_FLOAT, FFL_SPAWNTEMP},
  71.     {"maxpitch", STOFS(maxpitch), F_FLOAT, FFL_SPAWNTEMP},
  72.     {"nextmap", STOFS(nextmap), F_LSTRING, FFL_SPAWNTEMP}
  73. };
  74.  
  75. // -------- just for savegames ----------
  76. // all pointer fields should be listed here, or savegames
  77. // won't work properly (they will crash and burn).
  78. // this wasn't just tacked on to the fields array, because
  79. // these don't need names, we wouldn't want map fields using
  80. // some of these, and if one were accidentally present twice
  81. // it would double swizzle (fuck) the pointer.
  82.  
  83. field_t        savefields[] =
  84. {
  85.     {"", FOFS(classname), F_LSTRING},
  86.     {"", FOFS(target), F_LSTRING},
  87.     {"", FOFS(targetname), F_LSTRING},
  88.     {"", FOFS(killtarget), F_LSTRING},
  89.     {"", FOFS(team), F_LSTRING},
  90.     {"", FOFS(pathtarget), F_LSTRING},
  91.     {"", FOFS(deathtarget), F_LSTRING},
  92.     {"", FOFS(combattarget), F_LSTRING},
  93.     {"", FOFS(model), F_LSTRING},
  94.     {"", FOFS(map), F_LSTRING},
  95.     {"", FOFS(message), F_LSTRING},
  96.  
  97.     {"", FOFS(client), F_CLIENT},
  98.     {"", FOFS(item), F_ITEM},
  99.  
  100.     {"", FOFS(goalentity), F_EDICT},
  101.     {"", FOFS(movetarget), F_EDICT},
  102.     {"", FOFS(enemy), F_EDICT},
  103.     {"", FOFS(oldenemy), F_EDICT},
  104.     {"", FOFS(activator), F_EDICT},
  105.     {"", FOFS(groundentity), F_EDICT},
  106.     {"", FOFS(teamchain), F_EDICT},
  107.     {"", FOFS(teammaster), F_EDICT},
  108.     {"", FOFS(owner), F_EDICT},
  109.     {"", FOFS(mynoise), F_EDICT},
  110.     {"", FOFS(mynoise2), F_EDICT},
  111.     {"", FOFS(target_ent), F_EDICT},
  112.     {"", FOFS(chain), F_EDICT},
  113.  
  114.     {NULL, 0, F_INT}
  115. };
  116.  
  117. field_t        levelfields[] =
  118. {
  119.     {"", LLOFS(changemap), F_LSTRING},
  120.  
  121.     {"", LLOFS(sight_client), F_EDICT},
  122.     {"", LLOFS(sight_entity), F_EDICT},
  123.     {"", LLOFS(sound_entity), F_EDICT},
  124.     {"", LLOFS(sound2_entity), F_EDICT},
  125.  
  126.     {NULL, 0, F_INT}
  127. };
  128.  
  129. field_t        clientfields[] =
  130. {
  131.     {"", CLOFS(pers.weapon), F_ITEM},
  132.     {"", CLOFS(pers.lastweapon), F_ITEM},
  133.     {"", CLOFS(newweapon), F_ITEM},
  134.  
  135.     {NULL, 0, F_INT}
  136. };
  137.  
  138. /*
  139. ============
  140. InitGame
  141.  
  142. This will be called when the dll is first loaded, which
  143. only happens when a new game is started or a save game
  144. is loaded.
  145. ============
  146. */
  147. void InitGame (void)
  148. {
  149.     gi.dprintf ("==== InitGame ====\n");
  150.  
  151.     gun_x = gi.cvar ("gun_x", "0", 0);
  152.     gun_y = gi.cvar ("gun_y", "0", 0);
  153.     gun_z = gi.cvar ("gun_z", "0", 0);
  154.  
  155.     //FIXME: sv_ prefix is wrong for these
  156.     sv_rollspeed = gi.cvar ("sv_rollspeed", "200", 0);
  157.     sv_rollangle = gi.cvar ("sv_rollangle", "2", 0);
  158.     sv_maxvelocity = gi.cvar ("sv_maxvelocity", "2000", 0);
  159.     sv_gravity = gi.cvar ("sv_gravity", "800", 0);
  160.  
  161.     // noset vars
  162.     dedicated = gi.cvar ("dedicated", "0", CVAR_NOSET);
  163.  
  164.     // latched vars
  165.     sv_cheats = gi.cvar ("cheats", "0", CVAR_SERVERINFO|CVAR_LATCH);
  166.     gi.cvar ("gamename", GAMEVERSION , CVAR_SERVERINFO | CVAR_LATCH);
  167.     gi.cvar ("gamedate", __DATE__ , CVAR_SERVERINFO | CVAR_LATCH);
  168.  
  169.     maxclients = gi.cvar ("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH);
  170.     deathmatch = gi.cvar ("deathmatch", "0", CVAR_LATCH);
  171.     coop = gi.cvar ("coop", "0", CVAR_LATCH);
  172.     skill = gi.cvar ("skill", "1", CVAR_LATCH);
  173.     maxentities = gi.cvar ("maxentities", "1024", CVAR_LATCH);
  174.  
  175. //ZOID
  176. //This game.dll only supports deathmatch
  177.     if (!deathmatch->value) {
  178.         gi.dprintf("Forcing deathmatch.");
  179.         gi.cvar_set("deathmatch", "1");
  180.     }
  181.     //force coop off
  182.     if (coop->value)
  183.         gi.cvar_set("coop", "0");
  184. //ZOID
  185.  
  186.  
  187.     // change anytime vars
  188.     dmflags = gi.cvar ("dmflags", "0", CVAR_SERVERINFO);
  189.     fraglimit = gi.cvar ("fraglimit", "0", CVAR_SERVERINFO);
  190.     timelimit = gi.cvar ("timelimit", "0", CVAR_SERVERINFO);
  191. //ZOID
  192.     capturelimit = gi.cvar ("capturelimit", "0", CVAR_SERVERINFO);
  193.     instantweap = gi.cvar ("instantweap", "0", CVAR_SERVERINFO);
  194. //ZOID
  195.      password = gi.cvar ("password", "", CVAR_USERINFO);
  196.     filterban = gi.cvar ("filterban", "1", 0);
  197.  
  198.     g_select_empty = gi.cvar ("g_select_empty", "0", CVAR_ARCHIVE);
  199.  
  200.     run_pitch = gi.cvar ("run_pitch", "0.002", 0);
  201.     run_roll = gi.cvar ("run_roll", "0.005", 0);
  202.     bob_up  = gi.cvar ("bob_up", "0.005", 0);
  203.     bob_pitch = gi.cvar ("bob_pitch", "0.002", 0);
  204.     bob_roll = gi.cvar ("bob_roll", "0.002", 0);
  205.  
  206.     // flood control
  207.     flood_msgs = gi.cvar ("flood_msgs", "4", 0);
  208.     flood_persecond = gi.cvar ("flood_persecond", "4", 0);
  209.     flood_waitdelay = gi.cvar ("flood_waitdelay", "10", 0);
  210.  
  211.     // dm map list
  212.     sv_maplist = gi.cvar ("sv_maplist", "", 0);
  213.  
  214.     // items
  215.     InitItems ();
  216.  
  217.     Com_sprintf (game.helpmessage1, sizeof(game.helpmessage1), "");
  218.  
  219.     Com_sprintf (game.helpmessage2, sizeof(game.helpmessage2), "");
  220.  
  221.     // initialize all entities for this game
  222.     game.maxentities = maxentities->value;
  223.     g_edicts =  gi.TagMalloc (game.maxentities * sizeof(g_edicts[0]), TAG_GAME);
  224.     globals.edicts = g_edicts;
  225.     globals.max_edicts = game.maxentities;
  226.  
  227.     // initialize all clients for this game
  228.     game.maxclients = maxclients->value;
  229.     game.clients = gi.TagMalloc (game.maxclients * sizeof(game.clients[0]), TAG_GAME);
  230.     globals.num_edicts = game.maxclients+1;
  231.  
  232. //ZOID
  233.     CTFInit();
  234. //ZOID
  235. }
  236.  
  237. //=========================================================
  238.  
  239. void WriteField1 (FILE *f, field_t *field, byte *base)
  240. {
  241.     void        *p;
  242.     int            len;
  243.     int            index;
  244.  
  245.     p = (void *)(base + field->ofs);
  246.     switch (field->type)
  247.     {
  248.     case F_INT:
  249.     case F_FLOAT:
  250.     case F_ANGLEHACK:
  251.     case F_VECTOR:
  252.     case F_IGNORE:
  253.         break;
  254.  
  255.     case F_LSTRING:
  256.     case F_GSTRING:
  257.         if ( *(char **)p )
  258.             len = strlen(*(char **)p) + 1;
  259.         else
  260.             len = 0;
  261.         *(int *)p = len;
  262.         break;
  263.     case F_EDICT:
  264.         if ( *(edict_t **)p == NULL)
  265.             index = -1;
  266.         else
  267.             index = *(edict_t **)p - g_edicts;
  268.         *(int *)p = index;
  269.         break;
  270.     case F_CLIENT:
  271.         if ( *(gclient_t **)p == NULL)
  272.             index = -1;
  273.         else
  274.             index = *(gclient_t **)p - game.clients;
  275.         *(int *)p = index;
  276.         break;
  277.     case F_ITEM:
  278.         if ( *(edict_t **)p == NULL)
  279.             index = -1;
  280.         else
  281.             index = *(gitem_t **)p - itemlist;
  282.         *(int *)p = index;
  283.         break;
  284.  
  285.     default:
  286.         gi.error ("WriteEdict: unknown field type");
  287.     }
  288. }
  289.  
  290. void WriteField2 (FILE *f, field_t *field, byte *base)
  291. {
  292.     int            len;
  293.     void        *p;
  294.  
  295.     p = (void *)(base + field->ofs);
  296.     switch (field->type)
  297.     {
  298.     case F_LSTRING:
  299.     case F_GSTRING:
  300.         if ( *(char **)p )
  301.         {
  302.             len = strlen(*(char **)p) + 1;
  303.             fwrite (*(char **)p, len, 1, f);
  304.         }
  305.         break;
  306.     }
  307. }
  308.  
  309. void ReadField (FILE *f, field_t *field, byte *base)
  310. {
  311.     void        *p;
  312.     int            len;
  313.     int            index;
  314.  
  315.     p = (void *)(base + field->ofs);
  316.     switch (field->type)
  317.     {
  318.     case F_INT:
  319.     case F_FLOAT:
  320.     case F_ANGLEHACK:
  321.     case F_VECTOR:
  322.     case F_IGNORE:
  323.         break;
  324.  
  325.     case F_LSTRING:
  326.         len = *(int *)p;
  327.         if (!len)
  328.             *(char **)p = NULL;
  329.         else
  330.         {
  331.             *(char **)p = gi.TagMalloc (len, TAG_LEVEL);
  332.             fread (*(char **)p, len, 1, f);
  333.         }
  334.         break;
  335.     case F_GSTRING:
  336.         len = *(int *)p;
  337.         if (!len)
  338.             *(char **)p = NULL;
  339.         else
  340.         {
  341.             *(char **)p = gi.TagMalloc (len, TAG_GAME);
  342.             fread (*(char **)p, len, 1, f);
  343.         }
  344.         break;
  345.     case F_EDICT:
  346.         index = *(int *)p;
  347.         if ( index == -1 )
  348.             *(edict_t **)p = NULL;
  349.         else
  350.             *(edict_t **)p = &g_edicts[index];
  351.         break;
  352.     case F_CLIENT:
  353.         index = *(int *)p;
  354.         if ( index == -1 )
  355.             *(gclient_t **)p = NULL;
  356.         else
  357.             *(gclient_t **)p = &game.clients[index];
  358.         break;
  359.     case F_ITEM:
  360.         index = *(int *)p;
  361.         if ( index == -1 )
  362.             *(gitem_t **)p = NULL;
  363.         else
  364.             *(gitem_t **)p = &itemlist[index];
  365.         break;
  366.  
  367.     default:
  368.         gi.error ("ReadEdict: unknown field type");
  369.     }
  370. }
  371.  
  372. //=========================================================
  373.  
  374. /*
  375. ==============
  376. WriteClient
  377.  
  378. All pointer variables (except function pointers) must be handled specially.
  379. ==============
  380. */
  381. void WriteClient (FILE *f, gclient_t *client)
  382. {
  383.     field_t        *field;
  384.     gclient_t    temp;
  385.     
  386.     // all of the ints, floats, and vectors stay as they are
  387.     temp = *client;
  388.  
  389.     // change the pointers to lengths or indexes
  390.     for (field=clientfields ; field->name ; field++)
  391.     {
  392.         WriteField1 (f, field, (byte *)&temp);
  393.     }
  394.  
  395.     // write the block
  396.     fwrite (&temp, sizeof(temp), 1, f);
  397.  
  398.     // now write any allocated data following the edict
  399.     for (field=clientfields ; field->name ; field++)
  400.     {
  401.         WriteField2 (f, field, (byte *)client);
  402.     }
  403. }
  404.  
  405. /*
  406. ==============
  407. ReadClient
  408.  
  409. All pointer variables (except function pointers) must be handled specially.
  410. ==============
  411. */
  412. void ReadClient (FILE *f, gclient_t *client)
  413. {
  414.     field_t        *field;
  415.  
  416.     fread (client, sizeof(*client), 1, f);
  417.  
  418.     for (field=clientfields ; field->name ; field++)
  419.     {
  420.         ReadField (f, field, (byte *)client);
  421.     }
  422. }
  423.  
  424. /*
  425. ============
  426. WriteGame
  427.  
  428. This will be called whenever the game goes to a new level,
  429. and when the user explicitly saves the game.
  430.  
  431. Game information include cross level data, like multi level
  432. triggers, help computer info, and all client states.
  433.  
  434. A single player death will automatically restore from the
  435. last save position.
  436. ============
  437. */
  438. void WriteGame (char *filename, qboolean autosave)
  439. {
  440.     FILE    *f;
  441.     int        i;
  442.     char    str[16];
  443.  
  444.     if (!autosave)
  445.         SaveClientData ();
  446.  
  447.     f = fopen (filename, "wb");
  448.     if (!f)
  449.         gi.error ("Couldn't open %s", filename);
  450.  
  451.     memset (str, 0, sizeof(str));
  452.     strcpy (str, __DATE__);
  453.     fwrite (str, sizeof(str), 1, f);
  454.  
  455.     game.autosaved = autosave;
  456.     fwrite (&game, sizeof(game), 1, f);
  457.     game.autosaved = false;
  458.  
  459.     for (i=0 ; i<game.maxclients ; i++)
  460.         WriteClient (f, &game.clients[i]);
  461.  
  462.     fclose (f);
  463. }
  464.  
  465. void ReadGame (char *filename)
  466. {
  467.     FILE    *f;
  468.     int        i;
  469.     char    str[16];
  470.  
  471.     gi.FreeTags (TAG_GAME);
  472.  
  473.     f = fopen (filename, "rb");
  474.     if (!f)
  475.         gi.error ("Couldn't open %s", filename);
  476.  
  477.     fread (str, sizeof(str), 1, f);
  478.     if (strcmp (str, __DATE__))
  479.     {
  480.         fclose (f);
  481.         gi.error ("Savegame from an older version.\n");
  482.     }
  483.  
  484.     g_edicts =  gi.TagMalloc (game.maxentities * sizeof(g_edicts[0]), TAG_GAME);
  485.     globals.edicts = g_edicts;
  486.  
  487.     fread (&game, sizeof(game), 1, f);
  488.     game.clients = gi.TagMalloc (game.maxclients * sizeof(game.clients[0]), TAG_GAME);
  489.     for (i=0 ; i<game.maxclients ; i++)
  490.         ReadClient (f, &game.clients[i]);
  491.  
  492.     fclose (f);
  493. }
  494.  
  495. //==========================================================
  496.  
  497.  
  498. /*
  499. ==============
  500. WriteEdict
  501.  
  502. All pointer variables (except function pointers) must be handled specially.
  503. ==============
  504. */
  505. void WriteEdict (FILE *f, edict_t *ent)
  506. {
  507.     field_t        *field;
  508.     edict_t        temp;
  509.  
  510.     // all of the ints, floats, and vectors stay as they are
  511.     temp = *ent;
  512.  
  513.     // change the pointers to lengths or indexes
  514.     for (field=savefields ; field->name ; field++)
  515.     {
  516.         WriteField1 (f, field, (byte *)&temp);
  517.     }
  518.  
  519.     // write the block
  520.     fwrite (&temp, sizeof(temp), 1, f);
  521.  
  522.     // now write any allocated data following the edict
  523.     for (field=savefields ; field->name ; field++)
  524.     {
  525.         WriteField2 (f, field, (byte *)ent);
  526.     }
  527.  
  528. }
  529.  
  530. /*
  531. ==============
  532. WriteLevelLocals
  533.  
  534. All pointer variables (except function pointers) must be handled specially.
  535. ==============
  536. */
  537. void WriteLevelLocals (FILE *f)
  538. {
  539.     field_t        *field;
  540.     level_locals_t        temp;
  541.  
  542.     // all of the ints, floats, and vectors stay as they are
  543.     temp = level;
  544.  
  545.     // change the pointers to lengths or indexes
  546.     for (field=levelfields ; field->name ; field++)
  547.     {
  548.         WriteField1 (f, field, (byte *)&temp);
  549.     }
  550.  
  551.     // write the block
  552.     fwrite (&temp, sizeof(temp), 1, f);
  553.  
  554.     // now write any allocated data following the edict
  555.     for (field=levelfields ; field->name ; field++)
  556.     {
  557.         WriteField2 (f, field, (byte *)&level);
  558.     }
  559. }
  560.  
  561.  
  562. /*
  563. ==============
  564. ReadEdict
  565.  
  566. All pointer variables (except function pointers) must be handled specially.
  567. ==============
  568. */
  569. void ReadEdict (FILE *f, edict_t *ent)
  570. {
  571.     field_t        *field;
  572.  
  573.     fread (ent, sizeof(*ent), 1, f);
  574.  
  575.     for (field=savefields ; field->name ; field++)
  576.     {
  577.         ReadField (f, field, (byte *)ent);
  578.     }
  579. }
  580.  
  581. /*
  582. ==============
  583. ReadLevelLocals
  584.  
  585. All pointer variables (except function pointers) must be handled specially.
  586. ==============
  587. */
  588. void ReadLevelLocals (FILE *f)
  589. {
  590.     field_t        *field;
  591.  
  592.     fread (&level, sizeof(level), 1, f);
  593.  
  594.     for (field=levelfields ; field->name ; field++)
  595.     {
  596.         ReadField (f, field, (byte *)&level);
  597.     }
  598. }
  599.  
  600. /*
  601. =================
  602. WriteLevel
  603.  
  604. =================
  605. */
  606. void WriteLevel (char *filename)
  607. {
  608.     int        i;
  609.     edict_t    *ent;
  610.     FILE    *f;
  611.     void    *base;
  612.  
  613.     f = fopen (filename, "wb");
  614.     if (!f)
  615.         gi.error ("Couldn't open %s", filename);
  616.  
  617.     // write out edict size for checking
  618.     i = sizeof(edict_t);
  619.     fwrite (&i, sizeof(i), 1, f);
  620.  
  621.     // write out a function pointer for checking
  622.     base = (void *)InitGame;
  623.     fwrite (&base, sizeof(base), 1, f);
  624.  
  625.     // write out level_locals_t
  626.     WriteLevelLocals (f);
  627.  
  628.     // write out all the entities
  629.     for (i=0 ; i<globals.num_edicts ; i++)
  630.     {
  631.         ent = &g_edicts[i];
  632.         if (!ent->inuse)
  633.             continue;
  634.         fwrite (&i, sizeof(i), 1, f);
  635.         WriteEdict (f, ent);
  636.     }
  637.     i = -1;
  638.     fwrite (&i, sizeof(i), 1, f);
  639.  
  640.     fclose (f);
  641. }
  642.  
  643.  
  644. /*
  645. =================
  646. ReadLevel
  647.  
  648. SpawnEntities will allready have been called on the
  649. level the same way it was when the level was saved.
  650.  
  651. That is necessary to get the baselines
  652. set up identically.
  653.  
  654. The server will have cleared all of the world links before
  655. calling ReadLevel.
  656.  
  657. No clients are connected yet.
  658. =================
  659. */
  660. void ReadLevel (char *filename)
  661. {
  662.     int        entnum;
  663.     FILE    *f;
  664.     int        i;
  665.     void    *base;
  666.     edict_t    *ent;
  667.  
  668.     f = fopen (filename, "rb");
  669.     if (!f)
  670.         gi.error ("Couldn't open %s", filename);
  671.  
  672.     // free any dynamic memory allocated by loading the level
  673.     // base state
  674.     gi.FreeTags (TAG_LEVEL);
  675.  
  676.     // wipe all the entities
  677.     memset (g_edicts, 0, game.maxentities*sizeof(g_edicts[0]));
  678.     globals.num_edicts = maxclients->value+1;
  679.  
  680.     // check edict size
  681.     fread (&i, sizeof(i), 1, f);
  682.     if (i != sizeof(edict_t))
  683.     {
  684.         fclose (f);
  685.         gi.error ("ReadLevel: mismatched edict size");
  686.     }
  687.  
  688.     // check function pointer base address
  689.     fread (&base, sizeof(base), 1, f);
  690.     if (base != (void *)InitGame)
  691.     {
  692.         fclose (f);
  693.         gi.error ("ReadLevel: function pointers have moved");
  694.     }
  695.  
  696.     // load the level locals
  697.     ReadLevelLocals (f);
  698.  
  699.     // load all the entities
  700.     while (1)
  701.     {
  702.         if (fread (&entnum, sizeof(entnum), 1, f) != 1)
  703.         {
  704.             fclose (f);
  705.             gi.error ("ReadLevel: failed to read entnum");
  706.         }
  707.         if (entnum == -1)
  708.             break;
  709.         if (entnum >= globals.num_edicts)
  710.             globals.num_edicts = entnum+1;
  711.  
  712.         ent = &g_edicts[entnum];
  713.         ReadEdict (f, ent);
  714.  
  715.         // let the server rebuild world links for this ent
  716.         memset (&ent->area, 0, sizeof(ent->area));
  717.         gi.linkentity (ent);
  718.     }
  719.  
  720.     fclose (f);
  721.  
  722.     // mark all clients as unconnected
  723.     for (i=0 ; i<maxclients->value ; i++)
  724.     {
  725.         ent = &g_edicts[i+1];
  726.         ent->client = game.clients + i;
  727.         ent->client->pers.connected = false;
  728.     }
  729.  
  730.     // do any load time things at this point
  731.     for (i=0 ; i<globals.num_edicts ; i++)
  732.     {
  733.         ent = &g_edicts[i];
  734.  
  735.         if (!ent->inuse)
  736.             continue;
  737.  
  738.         // fire any cross-level triggers
  739.         if (ent->classname)
  740.             if (strcmp(ent->classname, "target_crosslevel_target") == 0)
  741.                 ent->nextthink = level.time + ent->delay;
  742.     }
  743. }
  744.  
  745.